# app.py

from flask import Flask, render_template, request, redirect, url_for, jsonify
from model import *  # 导入 User 数据模型和数据库实例
from database import init_db  # 导入数据库初始化函数
from flask_cors import CORS 
import logging
from flask import Flask, request, jsonify
# from flask_uploads import UploadSet, configure_uploads, IMAGES
import base64
import os
# import numpy as np
# import cv2
from io import BytesIO
import random
# from yolov5.yolo_copy import yolo_run ,args



# 设置日志配置
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(levelname)s %(name)s %(threadName)s : %(message)s')

app = Flask(__name__)
CORS(app)


# photos = UploadSet('photos', IMAGES)

app.config.from_object('config')
# app.config['UPLOADED_PHOTOS_DEST'] = '/Users/star/Documents/课程_比赛_科研/课程实验/软件工程/soft-engineer/img'
# configure_uploads(app, photos)

# 初始化数据库
init_db(app)

@app.route('/api/users', methods=['GET', 'POST'])
def users():
    if request.method == 'POST':
        app.logger.debug('Headers: %s', request.headers)
        app.logger.debug('Body: %s', request.data.decode('utf-8'))  # 解码二进制的请求体
        data = request.get_json()
        name = data.get('userName')
        pwd = data.get('pwd')
        app.logger.debug('Received POST request with name: %s and password: %s', name, pwd)

        existing_user = User.query.filter_by(userName=name, pwd=pwd).first()
        if existing_user:
            app.logger.debug('login successfully!')
            return jsonify({'success': 1}), 201
        else:
            app.logger.debug('login failed!')
            return jsonify({'success': 0}), 201

@app.route('/api/register', methods=['POST', 'GET'])
def handle_register():
    data = request.get_json()
    userName = data.get('userName')
    pwd = data.get('pwd')
    existing_user = User.query.filter_by(userName = userName).first()
    if existing_user:
        app.logger.debug('User is already existed!')
        return jsonify({'success' : 0}), 201
    else:
        user = User(userName, pwd)
        try:
            db.session.add(user)
            db.session.commit()
            return jsonify({'success' : 1}), 201
        except Exception as e:
            app.logger.error('Error register User: %s',e)
            db.session.rollback()
            return jsonify({'success' : 0}), 201


@app.route('/api/img', methods=['POST'])
def save_image():
    img_data = request.json['imgData']
    
    # Removing the 'data:image/png;base64,' part from the string
    img_data = img_data.split(",")[1]

    # Decoding the base64 string
    img_bytes = base64.b64decode(img_data)
    
    # 使用BytesIO处理这些字节数据
    img_buf = BytesIO(img_bytes)
    
    # 将字节数据转换为numpy数组
    img_arr = np.frombuffer(img_buf.getvalue(), dtype=np.uint8)
    img_np = cv2.imdecode(img_arr, cv2.IMREAD_COLOR)
    yolostatus = yolo.detect(img_np)
    # print(yolostatus)
    # Save to a file
    # with open(os.path.join("/Users/star/Documents/课程_比赛_科研/课程实验/软件工程/soft-engineer/img", "saved_image.png"), "wb") as f:
    #     f.write(img_bytes)
    if yolostatus != 0:
        yolostatus = 1
    ans = {'focus':yolostatus}
    return jsonify(ans)

# recordrevised is used to access to the Revised database and update the data in it.
@app.route('/api/recordrevised',methods=['GET','POST'])
def recordrevised():
    if request.method == 'POST':
        data = request.get_json()
        userName = data.get('userName')
        listName = data.get('listName')
        location = data.get('location')
        startedAt = data.get('startedAt')
        updatedAt = data.get('updatedAt')
        app.logger.debug('Received POST request with userName: %s and listName: %s and location: %s and startedAt: %s and updatedAt: %s', userName, listName, location, startedAt, updatedAt)
        existing_user = Revised.query.filter_by(userName=userName,listName=listName).first()
        
        if existing_user:
            existing_user.location = location
            existing_user.startedAt = startedAt
            existing_user.updatedAt = updatedAt
            try:
                db.session.commit()
                return jsonify({'message': 'User revised update successfully'}), 201
            except Exception as e:
                app.logger.error('Error update user revise: %s', e)
                db.session.rollback()
                return jsonify({'message': 'Error updating user revise'}), 500
        else:
            new_user = Revised(userName=userName,listName=listName,location=location,startedAt=startedAt,updatedAt=updatedAt)
            db.session.add(new_user)
            try:
                db.session.commit()
                app.logger.debug('User revised created successfully')
                return jsonify({'message': 'User revised created successfully'}), 201
            except Exception as e:
                app.logger.error('Error creating user revised: %s', e)
                db.session.rollback()
                return jsonify({'message': 'Error creating user revised'}), 500

# get revised is used to get access to Revised database to get the user's 
# information(location, startedAt, updatedAt) in every list(listName)
@app.route('/api/getrevised',methods=['GET','POST'])
def getrevised():
    if request.method == 'POST':
        data = request.get_json()
        userName = data.get('userName')
        app.logger.debug('getrevised: Received POST request with userName: %s', userName)
        existing_user = Revised.query.filter_by(userName=userName)
        if existing_user.first():
            result = {}
            for user in existing_user:
                user_data={
                    'location':user.location,
                    'startedAt':user.startedAt,
                    'updatedAt':user.updatedAt
                }
                result[user.listName] = user_data
            return jsonify(result),201
        else:
            return jsonify({'location': 0,'startedAt': 0,'updatedAt': 0}), 201

# recordlearned is used to get access to the database Learned
# it will get the user's information(userName, period, stage, updatedAt, en)
# and save it to the database
@app.route('/api/recordlearned',methods=['GET','POST'])
def recordlearned():
    app.logger.debug('recordlearned: here!!!')
    if request.method == 'POST':
        app.logger.debug('recordlearned: Im an in !!!!!!!!')
        data = request.get_json()
        userName = data.get('userName')
        en = data.get('en')
        period = data.get('period')
        stage = data.get('stage')
        updatedAt = data.get('updatedAt')
        zh = data.get('zh')
        app.logger.debug('recordlearned: Received POST request with userName: %s and en: %s and period: %s and stage: %s and updatedAt: %s', userName, en, period, stage, updatedAt)
        # app.logger.debug('The length of zh is %s', len(zh))
        existing_user = Learned.query.filter_by(userName=userName,en=en).first()
        
        if existing_user:
            existing_user.period = period
            existing_user.stage = stage
            existing_user.updatedAt = updatedAt
            try:
                db.session.commit()
                return jsonify({'message': 'User learned update successfully'}), 201
            except Exception as e:
                app.logger.error('Error update user learn: %s', e)
                db.session.rollback()
                return jsonify({'message': 'Error update user learn'}), 500
        else:
            new_user = Learned(userName=userName,en=en,period=period,stage=stage,updatedAt=updatedAt)
            db.session.add(new_user)
            try:
                db.session.commit()
                app.logger.debug('User learned created successfully')
                return jsonify({'message': 'User learned created successfully'}), 201
            except Exception as e:
                app.logger.error('Error creating user learned: %s', e)
                db.session.rollback()
                return jsonify({'message': 'Error record user learned'}), 500

# getlearned is used to get access to the Learned database
# it will get the user's information with the key user and the en
@app.route('/api/getlearned',methods=['GET','POST'])
def getlearnd():
    if request.method == 'POST':
        data = request.get_json()
        userName = data.get('userName')
        app.logger.debug('getlearned: Received POST request with userName: %s ', userName )
        existing_user = Learned.query.filter_by(userName=userName)
        if existing_user.first():
            result = {}
            for user in existing_user:
                existing_zh = Vocabulary.query.filter_by(en=user.en).first()
                if not existing_zh:
                    zh = 0
                else:
                    zh = existing_zh.zh
                user_data = {
                    'en': user.en,
                    'period': user.period,
                    'stage': user.stage,
                    'updatedAt': user.updatedAt,
                    'zh': zh
                }
                result[user.en] = user_data
            return jsonify(result), 201
        else:
            return jsonify({'en':0,'period': 0,'stage': 0,'updatedAt': 0,'zh': 0}), 201

# getresult will get access to every result from the Revised database
# it will calculate the process in every subject
# it will also calculate the focus time

@app.route('/api/getresult',methods=['GET','POST'])
def getresult():
    if request.method == 'POST':
        data = request.get_json()
        userName = data.get('userName')
        app.logger.debug('getresult: Received POST request with userName: %s ', userName)
        total_cn = 0
        actual_cn = 0
        total_mt = 0
        actual_mt = 0
        total_en = 0
        actual_en = 0
        existing_cn = Level.query.filter_by(subject = 'cn')
        if existing_cn.first():
            for cn in existing_cn:
                total_cn = total_cn + cn.total
                cn_name = cn.listName
                existing_user = Revised.query.filter_by(userName = userName, listName = cn_name).first()
                if not existing_user:
                    actual_cn = actual_cn + 0
                else:
                    actual_cn = actual_cn + existing_user.location
        existing_mt = Level.query.filter_by(subject = 'math')
        if existing_mt.first():
            for mt in existing_mt:
                total_mt = total_mt + mt.total
                mt_name = mt.listName
                existing_user = Revised.query.filter_by(userName = userName, listName = mt_name).first()
                if not existing_user:
                    actual_mt = actual_mt + 0
                else:
                    actual_mt = actual_mt + existing_user.location
        existing_en = Level.query.filter_by(subject = 'eg')
        if existing_en.first():
            for en in existing_en:
                total_en = total_en + en.total
                en_name = en.listName
                existing_user = Revised.query.filter_by(userName = userName, listName = en_name).first()
                if not existing_user:
                    actual_en = actual_en + 0
                else:
                    actual_en = actual_en + existing_user.location
        concentrate = 0.0
        existing_user = Focus.query.filter_by(userName = userName).first()
        if existing_user:
            if existing_user.total_frame==0:
                concentrate = 0.0
            else:
                concentrate = (existing_user.total_frame - existing_user.play_frame) / existing_user.total_frame
        result = {}
        print(total_cn)
        print(total_mt)
        print(total_en)
        mathprogress = actual_mt / total_mt
        englishprogress = actual_en / total_en
        chineseprogress = actual_cn / total_cn
        if mathprogress==1 and chineseprogress == 1 and englishprogress == 1:
            advise = '你已经从这里毕业了！祝你未来前程似锦！'
        elif mathprogress < 0.1 and chineseprogress < 0.1 and englishprogress < 0.1:
            advise = '别看建议了，快去做题！'
        elif mathprogress>(englishprogress + chineseprogress) / 2:
            math_better = Remark.query.filter_by(id = 1).all()
            if len(math_better) != 0:
                remark = random.choice(math_better)
                advise = remark.words
            else:
                advise = '你已经很棒了，继续保持！'
        elif (englishprogress + chineseprogress) / 2 > mathprogress:
            cn_and_eg_better = Remark.query.filter_by(id = 2).all()
            if len(cn_and_eg_better) != 0:
                remark = random.choice(cn_and_eg_better)
                advise = remark.words
            else:
                advise = '你已经很棒了，继续保持！'
        else:
            equal = Remark.query.filter_by(id = 3).all()
            if len(equal) != 0:
                remark = random.choice(equal)
                advise = remark.words
            else:
                advise = '你已经很棒了，继续保持！'
        print(userName)
        print(mathprogress)
        print(englishprogress)
        print(chineseprogress)
        print(concentrate)
        print(advise)
        user_data = {
            'userName': userName,
            'mathprogress': mathprogress,
            'englishprogress': englishprogress,
            'chineseprogress': chineseprogress,
            'focus': concentrate,
            'advise': advise
        }
        result[userName] = user_data
        return jsonify(result), 201

# handle_focus will get the user's concentrate and save it to the Focus database
@app.route('/api/focus', methods=['POST', 'GET'])
def handle_focus():
    data = request.get_json()
    userName = data.get('userName')
    play = data.get('play')
    not_play = data.get('notplay')

    existing_user = Focus.query.filter_by(userName = userName).first()
    if existing_user:
        existing_user.total_frame = existing_user.total_frame + play + not_play
        existing_user.play_frame = existing_user.play_frame + play
        try:
            db.session.commit()
            return jsonify({'message' : 'the focus is recorded successfully!'}), 201
        except Exception as e:
            app.logger.error('Error change the user''s focus info: %s', e)
            db.session.rollback()
            return jsonify({'message': 'Error change the user''s focus info'}), 500
    else:
        user_focus = Focus(userName, play, play+not_play)
        db.session.add(user_focus)
        try:
            db.session.commit()
            return jsonify({'message' : 'the focus is recorded successfully!'}), 201
        except Exception as e:
            app.logger.error('Error create the user''s focus info: %s', e)
            db.session.rollback()
            return jsonify({'message': 'Error change the user''s focus info'}), 500

@app.route('/', methods=['POST', 'GET'])
def hello():
    return 'helloworld!'

# 其他路由和视图函数...
if __name__ == '__main__':
    # yolo = yolo_run(args)
    
    app.run(host='0.0.0.0', port=8080, debug=True)  # 设置 debug=True 来启动调试模式

#写一个排序算法
